﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.Data.SqlClient;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace Com.ThrongIn.DAL
{
   public class DBInstance
    {
        // Methods
        private static void AddParameter(ref GenericDatabase db, ref DbCommand command, DbParameter[] parameters)
        {
            foreach (DbParameter param in parameters)
            {
                db.AddInParameter(command, param.ParameterName, param.DbType, param.Value);
            }
        }
        public static DataSet GetDataSet(string spName)
        {
            GenericDatabase genDB = EnterpriseLibraryContainer.Current.GetInstance<GenericDatabase>("ConnectionString");
            DbCommand dbCommand = genDB.GetStoredProcCommand("CALL " + spName + "");
            return genDB.ExecuteDataSet(dbCommand);
        }
        public static IDataReader GetReader(string spName)
        {
            GenericDatabase genDB = EnterpriseLibraryContainer.Current.GetInstance<GenericDatabase>("ConnectionString");
            DbCommand dbCommand = genDB.GetStoredProcCommand("CALL " + spName + "");
            return genDB.ExecuteReader(dbCommand);
        }
        public static IDataReader GetReader(string spName, DbParameter[] parameters)
        {
            GenericDatabase genDB = EnterpriseLibraryContainer.Current.GetInstance<GenericDatabase>("ConnectionString");
            string qmark = "(";
            for (int i = 0; i < parameters.Length-1; i++)
            {
                qmark = qmark + "?,";
            }
            qmark = qmark + "?)";
            DbCommand dbCommand = genDB.GetStoredProcCommand("CALL " + spName + qmark);
            if(parameters != null || parameters.Count()>0)
                AddParameter(ref genDB, ref dbCommand, parameters);
            return genDB.ExecuteReader(dbCommand);
        }
        public static int ExecuteNonQuery(string spName, DbParameter[] parameters)
        {
            GenericDatabase genDB = EnterpriseLibraryContainer.Current.GetInstance<GenericDatabase>("ConnectionString");
            string qmark = "(";
            for (int i = 0; i < parameters.Length - 1; i++)
            {
                qmark = qmark + "?,";
            }
            qmark = qmark + "?)";

            DbCommand dbCommand = genDB.GetStoredProcCommand("CALL " + spName + qmark);
            if (parameters != null || parameters.Count() > 0)
                AddParameter(ref genDB, ref dbCommand, parameters);
             return genDB.ExecuteNonQuery(dbCommand);
        }
        public static object ExecuteScalar(string spName, DbParameter[] parameters)
        {
            GenericDatabase genDB = EnterpriseLibraryContainer.Current.GetInstance<GenericDatabase>("ConnectionString");
            string qmark = "(";
            for (int i = 0; i < parameters.Length - 1; i++)
            {
                qmark = qmark + "?,";
            }
            qmark = qmark + "?)";
            DbCommand dbCommand = genDB.GetStoredProcCommand("CALL " + spName + qmark);
            if (parameters != null || parameters.Count() > 0)
                AddParameter(ref genDB, ref dbCommand, parameters);
            return genDB.ExecuteScalar(dbCommand);
        }
        public static DbParameter ParameterInstance(DbType type, string Name, object value, ParameterDirection? direction)
        {
            return new SqlParameter { DbType = type, ParameterName = Name, Value = value, Direction = !direction.HasValue ? ParameterDirection.Input : direction.Value };
        }

        public static List<T> PopulateEntities<T>(IDataReader dr)
        {
            List<T> entities = new List<T>();
            while (dr.Read())
            {
                T ent = Activator.CreateInstance<T>();
                PopulateEntity<T>(ent, dr);
                entities.Add(ent);
            }
            return entities;
        }

        public static void PopulateEntity<T>(T entity, IDataRecord record)
        {
            if ((record != null) && (record.FieldCount > 0))
            {
                Type type = entity.GetType();
                for (int i = 0; i < record.FieldCount; i++)
                {
                    if (DBNull.Value != record[i])
                    {
                        PropertyInfo property = type.GetProperty(record.GetName(i), BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                        if (property != null)
                        {
                            property.SetValue(entity, record[property.Name], null);
                        }
                    }
                }
            }
        }
    }
}
